<template>
  <div class="flex flex-col h-full bg-[#f5f5f5]">
    <BreadcrumbNav
      :items="breadcrumbs"
      :show-back="departmentStack.length > 0"
      @back="handleBack"
      @click="handleBreadcrumbClick"
      @search="onSearch"
    />
    <div
      v-if="isOverMaxNum && !cp_isSingleSelect"
      class="flex flex-row items-center pl-4 bg-[#FBE7E7] text-[#595959] gap-1 py-3"
    >
      <van-icon size="16px" name="clear" color="#F5222D" />
      <p class="text-sm">最多选{{ maxNum }}人</p>
    </div>
    <div>
      <van-search
        v-model="searchText"
        placeholder="请输入搜索姓名"
        @update:model-value="(v) => debounce(() => onSearch(v))"
        @search="onSearch"
      />
    </div>
    <div class="flex-auto overflow-y-auto">
      <ListSkeleton v-if="loading" :count="8" />
      <template v-else>
        <VirtualList
          v-if="filteredList.length > 0"
          class="flex flex-auto"
          ref="virtualListRef"
          :data="filteredList"
          :containerHeight="listContainerHeight"
          :itemHeight="itemHeight"
          :bufferSize="5"
        >
          <template #default="{ item, index }">
            <ListItem
              :key="item.id"
              :item="item"
              :selected="selectedTags.some((v) => v.id === item.id)"
              :get-avatar-color="getAvatarColor"
              :get-department-initial="getDepartmentInitial"
              :get-name-initial="getNameInitial"
              @click="handleItemClick"
              @select="handleSelect"
            />
          </template>
        </VirtualList>

        <van-empty v-else description="该部门无部门&人员" />
      </template>
    </div>

    <BottomBar :tags="selectedTags" @remove-tag="removeItem" @confirm="handleConfirm" />
  </div>
</template>

<script setup>
import { ref, computed, onMounted, defineProps } from "vue";
import { useMyXmateStore } from "@/store";
import { getToken } from "@/utils/auth";
import { searchInnerAttendPagerAPI } from "@/services/orderVisit";
import { getAllDprtAPI } from "@/services/myXmate";
import debounce from "@/utils/debounce";
import VirtualList from "@/components/VirtualList.vue";

import BreadcrumbNav from "./components/BreadcrumbNav.vue";
import ListItem from "./components/ListItem.vue";
import BottomBar from "./components/BottomBar.vue";
import ListSkeleton from "./components/ListSkeleton.vue";
import { getAvatarColor } from "@/utils/colorTool";
import { showLoadingToast, closeToast, showToast } from "vant";
import { getUserInfo } from "@/utils/auth";
import { generateHash } from "@/utils/num";
import { getCache, saveCache } from "@/utils/dbCache";

const props = defineProps({
  defaultTeamId: {
    type: String,
  },
  // // 是否在接口中限制只显示
  // onShowSelfDept: {
  //   type: Boolean,
  //   default: false
  // },
  // 默认是否要选中自己
  defaultSelectedSelf: {
    type: Boolean,
    default: false,
  },
  // 是否开启接口数组缓存
  enableCache: {
    type: Boolean,
    default: false,
  },
  // 是否为单选
  isSingleSelect: {
    type: Boolean,
    default: false,
  },
  // 是否允许取消自己
  enableCancelSelf: {
    type: Boolean,
    default: true,
  },
  defaultSelectedItems: {
    type: Array,
    default: () => [],
  },
  dprtArea: {
    type: String,
    default: "myDprt",
  },
  maxNum: {
    type: Number,
    default: 0,
  },
});

// 虚拟列表配置
const itemHeight = 80; // 预估每项高度
const listContainerHeight = ref(480);

const store = useMyXmateStore();
const currentDepartment = ref(null);
const departmentStack = ref([]);
const list = ref([]);
const rootDepartment = ref(null);
const searchText = ref("");
const loading = ref(false);
const selectedItems = ref(new Set(props.defaultSelectedItems));

const cp_isSingleSelect = computed(() => {
  return props.isSingleSelect || props.maxNum === 1;
});

// 初始化加载根部门数据
onMounted(async () => {
  if (props.dprtArea === "myDprt") {
    await getMyDprt();
  } else {
    await getAllDprt();
  }
  if (props.defaultSelectedSelf) {
    await searchSelf();
    if (selfInfo.value) {
      addItem(selfInfo.value);
    }
  }
});

async function searchInnerAttendPagerAction(name, deptIds, includeChildren) {
  const parameter = {
    name,
    deptIds,
    includeChildren,
  };
  const cacheKey = await generateHash(JSON.stringify(parameter));
  const cacheData = await getCache(cacheKey);

  if (props.enableCache && cacheData) {
    return cacheData;
  }
  const data = await searchInnerAttendPagerAPI(parameter);
  if (props.enableCache) {
    await saveCache(cacheKey, data);
  }
  return data;
}

/*
 * 1. 接口查找自己
 * 2. 将自己的信息添加选中信息中
 * 3. 属性新增是否可以取消自己
 * */
const selfInfo = ref();
async function searchSelf() {
  const userInfo = getUserInfo();
  if (!userInfo) {
    return;
  }
  const data = await searchInnerAttendPagerAction(
    userInfo.name,
    [rootDepartment.value.id],
    1
  );
  let peopleList = data.datas;
  peopleList = peopleList.filter(
    (item) => item.ssoUserId === userInfo.ssoUserId || item.id === userInfo.ssoUserId
  );
  if (peopleList.length > 0) {
    selfInfo.value = mapItem(peopleList[0]);
  }
}

async function getMyDprt() {
  loading.value = true;
  const data = await store.getMydprtAction();
  loading.value = false;
  if (props.defaultTeamId) {
    rootDepartment.value = findObjectById(data, props.defaultTeamId);
  } else {
    rootDepartment.value = data;
  }
  console.log("rootDepartment.value", rootDepartment.value);
  currentDepartment.value = rootDepartment.value;
  departmentStack.value.push({
    id: data.id,
    name: data.name,
    children: data.children || [],
  });
  await updateList(rootDepartment.value);
}

async function getAllDprt() {
  loading.value = true;

  const cacheKey = await generateHash(`getAllDprt+${getToken()}`);
  const cacheData = await getCache(cacheKey);

  let data;
  if (props.enableCache && cacheData) {
    data = cacheData;
  } else {
    data = await getAllDprtAPI();
    await saveCache(cacheKey, data);
  }

  loading.value = false;
  if (props.defaultTeamId) {
    rootDepartment.value = findObjectById(data, props.defaultTeamId);
  } else {
    rootDepartment.value = data;
  }
  console.log("rootDepartment.value", rootDepartment.value);
  currentDepartment.value = rootDepartment.value;
  departmentStack.value.push({
    id: data.id,
    name: data.name,
    children: data.children || [],
  });
  await updateList(rootDepartment.value);
}

// 将api数据映射为UI使用过的字段
function mapItem(staff) {
  return {
    id: staff.id,
    name: staff.fullname || staff.name || staff.username,
    type: "staff",
    title: staff.positionName || "",
    avatar: staff.imgUrl || "",
    selected: selectedItems.value.has(staff.id),
    deptId: staff.deptId,
    deptName: staff.deptName,
    username: staff.username,
  };
}

// 计算属性
const filteredList = computed(() => {
  if (searchText.value.length > 0) {
    return searchList.value.map((staff) => mapItem(staff));
  }
  return list.value.filter((item) =>
    item.name.toLowerCase().includes(searchText.value.toLowerCase())
  );
});

const isOverMaxNum = computed(() => {
  if (props.maxNum <= 0) {
    return false;
  }
  return selectedTags.value.length >= props.maxNum;
});

const selectedTags = computed(() => {
  return Array.from(selectedItems.value).map((v) => mapItem(v));
});

// 修改计算面包屑导航的逻辑
const breadcrumbs = computed(() => {
  if (!currentDepartment.value) return [];

  // 如果当前是根部门，只显示根部门
  if (currentDepartment.value.id === rootDepartment.value?.id) {
    return [
      {
        id: currentDepartment.value.id,
        name: currentDepartment.value.name,
      },
    ];
  }

  // 构建导航路径
  const path = [];

  // 添加导航栈中的部门
  path.push(...departmentStack.value);

  return path;
});

// 事件处理函数
async function handleItemClick(item) {
  console.log("handleItemClick", item);
  if (item.type === "department") {
    // 将当前部门添加到导航栈，只保存必要的信息
    departmentStack.value.push({
      id: item.id,
      name: item.name,
      children: item.children || [],
    });
    currentDepartment.value = item;
    await updateList(item);
  }
}

const handleSelect = (item) => {
  console.log("handleSelect", item);
  // 处理单选情况
  if (cp_isSingleSelect.value) {
    selectedItems.value.clear();
    addItem(item);
    return;
  }
  let isSelected = selectedTags.value.some((v) => v.id === item.id);
  if (isSelected) {
    removeItem(item);
    return;
  }

  if (isOverMaxNum.value && !cp_isSingleSelect.value) {
    showToast("超出可选最大上限");
    return;
  }

  addItem(item);
};

function isSelfItem(item) {
  const userInfo = getUserInfo();
  if (!userInfo) {
    return false;
  }
  return userInfo.ssoUserId === item.id;
}

const addItem = (item) => {
  let isSelected = selectedTags.value.some((v) => v.id === item.id);
  if (isSelected) {
    return;
  }
  selectedItems.value.add(item);
};

// 取消选择某个item
const removeItem = (tag) => {
  if (!props.enableCancelSelf) {
    if (isSelfItem(tag)) {
      showToast("不能取消自己");
      return;
    }
  }
  let array = Array.from(selectedItems.value);
  const index = array.findIndex((v) => v.id === tag.id);
  if (index > -1) {
    array.splice(index, 1);
    selectedItems.value = new Set(array);
  }
};

// 其他工具函数
function getDepartmentInitial(name) {
  // // 使用正则匹配中文、数字、英文
  const match = name.match(/[\u4e00-\u9fa5a-zA-Z0-9]/);
  return match ? match[0] : "部门";
}

function getNameInitial(name) {
  if (!name) {
    return "";
  }
  // 先过滤掉所有特殊字符，只保留中文、数字、英文
  const filteredName = name.replace(/[^\u4e00-\u9fa5a-zA-Z0-9]/g, "");

  // 如果过滤后的字符串为空，返回默认值
  if (!filteredName) return "U";

  // 获取第一个字符并转为大写（如果是英文的话）
  const initial = filteredName.charAt(0);
  return /[a-zA-Z]/.test(initial) ? initial.toUpperCase() : initial;
}

function handleConfirm() {
  emit("confirm", Array.from(selectedItems.value));
}

let peopleMap = ref({});
// API 相关函数
async function updateList(department) {
  if (!department) return;
  console.log("updateList", department);
  loading.value = true;
  try {
    list.value = [
      ...(department.children || []).map((dept) => ({
        id: dept.id,
        name: dept.name,
        type: "department",
        selected: false,
        children: dept.children || [],
      })),
    ];

    let staffList = [];

    // let cacheStaffList = peopleMap.value[department.id];
    // if (false) {
    //   staffList = cacheStaffList;
    // } else {
    const data = await searchInnerAttendPagerAction("", [department.id]);
    staffList = data.datas;
    peopleMap.value[department.id] = staffList;
    // }

    console.log("staffList: ", staffList);
    list.value = [...list.value, ...(staffList || []).map((staff) => mapItem(staff))];
    // }
  } catch (error) {
    console.error("Failed to load staff list:", error);
  } finally {
    loading.value = false;
  }
}

const searchList = ref([]);
async function onSearch(value) {
  console.log("onSearch: ", searchText.value);
  if (value.length === 0) {
    return;
  }
  searchText.value = value;
  searchList.value = [];
  showLoadingToast();
  const data = await searchInnerAttendPagerAction(
    searchText.value,
    [rootDepartment.value.id],
    1
  );
  let staffList = data.datas;
  searchList.value = staffList;
  closeToast();
  console.log("onSearch: ", searchList.value);
}

// 修改面包屑点击处理函数
async function handleBreadcrumbClick(index) {
  if (index === breadcrumbs.value.length - 1) return;

  if (index === 0) {
    // 点击根部门，清空导航栈，只保留根部门
    departmentStack.value = [
      {
        id: rootDepartment.value.id,
        name: rootDepartment.value.name,
      },
    ];
    currentDepartment.value = rootDepartment.value;
  } else {
    // 点击中间部门，更新导航栈到选中的位置
    departmentStack.value = departmentStack.value.slice(0, index + 1);
    const targetDepartment = departmentStack.value[index];
    currentDepartment.value = {
      id: targetDepartment.id,
      name: targetDepartment.name,
      type: "department",
      children: targetDepartment.children || [],
    };
  }

  await updateList(currentDepartment.value);
}

// 修改返回处理函数
async function handleBack() {
  if (departmentStack.value.length > 0) {
    const previousDepartment = departmentStack.value.pop();
    currentDepartment.value = {
      id: previousDepartment.id,
      name: previousDepartment.name,
      type: "department",
    };
    await updateList(currentDepartment.value);
  }
}

const emit = defineEmits(["confirm", "select"]);

function findObjectById(data, id) {
  if (data.id === id) {
    return data;
  }

  if (data.children && data.children.length > 0) {
    for (let child of data.children) {
      const result = findObjectById(child, id);
      if (result) {
        return result;
      }
    }
  }
  return null;
}
</script>

<style lang="less" scoped>
// .choose-people-view {
//   display: flex;
//   flex-direction: column;
//   background: #f5f5f5;

//   .people-list {
//     flex: 1;
//     overflow-y: auto;
//     -webkit-overflow-scrolling: touch;
//     padding-bottom: calc(60px + var(--selected-tags-height, 0px));
//   }
// }

//::-webkit-scrollbar {
//  display: none;
//}
</style>
